/*->c.vtkey */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"

#include "h.flex"


#include "h.def"
#include "h.wos"
#include "h.pr"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.key"
#include "h.dir"
#include "h.ftp"
#include "h.batch"
#include "h.serial"
#include "h.file"
#include "h.xext"

#include "h.term"

#include "h.tek"

#include "h.vxkey"

#include "h.vtdef"

#include "h.vtscr"
#include "h.vtsend"
#include "h.vtwimp"
#include "h.vtchar"
#include "h.vtprint"
#include "h.vtfile"
#include "h.vtlo"
#include "h.vtselect"

#include "h.vtkey"





/***************************************************************************/
/*

 Code to handle keyboard for VT terminals

*/
/***************************************************************************/


int autorate;

void setauto(int state)
{
  if(state) state=autorate;
/*  fx(196,state,0);  **/
}

void defauto(void)
{
/*  fx(196,autorate,0); */
}


/*****************************************************************************/
/* move around by page fulls */


/* home screen to cursor */
/* tops = offset of top of screen */
/* scrolly =  y value of top of window */


void vthomescreen(void)
{
 int scry;
 scry=tops*TTDY;
 getw(whandle[VTERM]);
 if((y1-y0)<(ttyy+1)*TTDY) scry+=(ttyy+1)*TTDY-(y1-y0);
 vtgoffset(scx,-scry);
}



void vtgostart(void)
{
 getw(whandle[VTERM]);
 vtgoffset(scx,0);
}



void vtgoend(void)
{
 int wwheight;
 getw(whandle[VTERM]);
 wwheight=y1-y0;
 scy=-buffsize*TTDY+wwheight;
 vtgoffset(scx,scy);
}



void vtpageup(void)
{
 int wwheight;
 getw(whandle[VTERM]);
 wwheight=y1-y0;
 scy=tscrolly+wwheight;
 if(scy>0) scy=0;
 vtgoffset(scx,scy);
}



void vtpagedown(void)
{
 int wwheight;
 getw(whandle[VTERM]);
 wwheight=y1-y0;
 scy=tscrolly-wwheight;
 if(scy<(-buffsize*TTDY+wwheight)) scy=-buffsize*TTDY+wwheight;
 vtgoffset(scx,scy);
}



void vtlineup(void)
{
 int wwheight;
 getw(whandle[VTERM]);
 wwheight=y1-y0;
 scy=tscrolly+TTDY;
 if(scy>0) scy=0;
 vtgoffset(scx,scy);
}




void vtlinedown(void)
{
 int wwheight;
 getw(whandle[VTERM]);
 wwheight=y1-y0;
 scy=tscrolly-TTDY;
 if(scy<(-buffsize*TTDY+wwheight)) scy=-buffsize*TTDY+wwheight;
 vtgoffset(scx,scy);
}





/*****************************************************************************/
                           /*****   VT 220   *****/


/* passed dcs string bytes and -1 on finish of string and -2 on start */
/* dcs states, dcst->   0 prefix, 1 key number, 2 hex data */ 
/* dcs keyno,  dcsk->   number of key
               dcsb->   number of bytes in buffer
               dcsx->   number of byte in key
*/



#define VT220STEP 32

char * vt220fnkeys[15];    /* space for 15 function keys */

void setvt220k(void)
{
 static int booted=0;
 int  i;
 int  key;

 if(!booted)
 {
  for(i=0;i<15;i++)
  {
   if(!flex_alloce((flex_ptr)&vt220fnkeys[i],VT220STEP)) break;
  }
  booted=1;
 }

 for(key=0,i=17;i<35;i++,key++)
 {
  if(i==22) i=23;
  else
  if(i==30) i=31;
  else
  if(i==27) i=28;

  if(vt220fnkeys[key]) sprintf(vt220fnkeys[key],"\33[%d~",i);
 }
 flock=0;
}



/* appends a byte to the end of a key string */
/* shortens key strings automatically        */

void vt220writekey(int keyno,int index,int byte)
{
 int size;

 if(vt220fnkeys[keyno])
 {
  size=flex_size((flex_ptr)&vt220fnkeys[keyno]);

  if((index+1)>=size)
  {
   if(!flex_extend((flex_ptr)&vt220fnkeys[keyno],size+VT220STEP)) return;
  }
  else
  if((size-(index+1))>VT220STEP)
                     flex_extend((flex_ptr)&vt220fnkeys[keyno],size-VT220STEP);

  vt220fnkeys[keyno][index]=byte;
  vt220fnkeys[keyno][index+1]=0;
 }
}



/*
  DCS Ps $ p string ST  downloads state info 


  DCS Ps $ t string ST  restore presentation state
      1 cursor information
      2 tabs

      cursor info
      Pr;Pc;Pp;Srend;Satt;Sflag;Pgl;Pgr;Scss;Sdesig

      Pr=row
      Pc=column
      Pp=1
      Srend=0x40+8(rev video on)+4(blink)+2(underline)+1(bold)
      Satt =0x40+(selective erase)
      Sflag=0x40+8(auto wrap pending)+4(SS3 pending)+2(SS2 pending)+
            1(origin mode on)
      Pgl=char set in GL 0,1,2,3
      Pgr=char set in GR 0,1,2,3
      Sdesig string of font idents

      tabs
      Pc;Pc;Pc;   ; can be /





 DCS $ q  string ST    report control function setting

          $}           set active status display
          "q           set character attribute erasable
          "p           set conformace level
          $~           set status line type
          r            set top and bottom margins
          m            set graphic rendition

 DCS Ps !u string ST   assign upss

                       Ps=0 94 chars
                       Ps=1 96
                       string ident

 DCS Pc; Pl | Ky1/St1 ... Kyn/Stn ST

                       Pc=0 clear all keys
                         =1 clear one key

                       Pl=0 lock the keys
                         =1 do not lock


 DCS Ps;.... Ps { string ST dload or clear soft chars

      1;%d;1;0;0;0{ @%c%c%c%c%c%c%c%c/%c%c%c%c%c%c%c%c

      define character %d

      1; 1;2{ @

      clear font

*/



void vteraseset(void)
{
 int i;
 int cn;

 for(i=1;i<96;i++)
 {
  cn=vtcsetmap[VTDRCS].map[i];
  vtclearchar(cn);
 }
}



/* define a char */


void dcsdefinechar(char * dcsb)
{
 int Pfn;   /* font number 0 and 1       */
 int Pcn;   /* starting character number */
 int Pe;    /* erase control, 0 erase all in this DRCS
                              1 erase chars being reloaded 
                              2 erase all chars in all DRCS */
 int Pcms;  /* char matrix size, 0 default (7x10), 1 not used, 2 5x10, 3 6x10
                                 4 7x10  */
 int Pw;    /* width attribute 0 default (80), 1 = 80, 2 = 132 */
 int Pt;    /* text/full cell  0 default (text), 1 text, 2 full-cell (not used)
             */
 char dscs1; /* ident char 0 */
 char dscs2; /* ident char 1 */

 int  cn;

 int c[8];
 int d[8];
 char defn[10];
 int  n;
 int  i;
 int  j;
 int  t;
 char * p;


 n=sscanf(dcsb,"%d;%d;%d;%d;%d;%d{%c%c",
                &Pfn,&Pcn,&Pe,&Pcms,&Pw,&Pt,&dscs1,&dscs2);

 if(n==8)
 {
  if(n==3 && (Pe==2 || Pe==0)) vteraseset();

  p=dcsb;
  while(*p!='{') p++;
  p+=3;


  while(1)     /* loop through character definitions */
  {
   for(i=0;i<8;i++) c[i]=d[i]=0;

   i=0;

   while(1)
   {
    c[i++]=*p;
    if(!(*p) || (*p)=='/' || i==8) break;
    p++;
   }


   if(*p)
   {
    p++;
    if(*p!='/') break;
    p++;
    if(!*p) break;
   }
   else break;

   j=0;

   while(1)
   {
    d[j++]=*p;
    if(!(*p) || j==i) break;
    p++;
   }


   if(j!=i) break;


   for(i=0;i<6;i++)
   {
    t=0;
    for(j=0;j<8;j++)
    {
     t=t<<1;
     t|=((c[7-j]-63)>>i) & 0x1;
    }
    defn[i]=t;
   }

   for(i=6;i<10;i++)
   {
    t=0;
    for(j=0;j<8;j++)
    {
     t=t<<1;
     t|=((d[7-j]-63)>>(i-6)) & 0x1;
    }
    defn[i]=t;
   }

   cn=vtcsetmap[VTDRCS].map[Pcn];
   vtdefinechar(defn,cn);
   Pcn++;

   if(*p)
   {
    p++;
    if((*p)!=';') break;
    p++;
    if(!*p) break;
   }
   else break;

  }
 }
 else
 {
  n=sscanf(dcsb,"%d;%d;%d{%c%c",&Pfn,&Pcn,&Pe,&dscs1,&dscs2);

  if(n==5 && (Pe==2 || Pe==0)) vteraseset();
 }
}






int vtfindident(char * ident)
{
 int    i;
 char * p;
 char * q;

 for(i=0;i<VTMAXSET;i++)
 {
  p=ident;
  q=vtcsetmap[i].ident;
  while(1)
  {
   if(!*q) return(i);
   if(!*p) break;
   if(*p++!=*q++) break;
  }
 }
 return(-1);
}







/* restore presenation state */
/*

  DCS Ps $ t string ST  restore presentation state
      1 cursor information
      2 tabs

      cursor info
      Pr;Pc;Pp;Srend;Satt;Sflag;Pgl;Pgr;Scss;Sdesig

      Pr=row
      Pc=column
      Pp=1
      Srend=0x40+8(rev video on)+4(blink)+2(underline)+1(bold)
      Satt =0x40+(selective erase)
      Sflag=0x40+8(auto wrap pending)+4(SS3 pending)+2(SS2 pending)+
            1(origin mode on)
      Pgl=char set in GL 0,1,2,3
      Pgr=char set in GR 0,1,2,3
      Sdesig string of font idents

      tabs
      Pc;Pc;Pc;   ; can be /

 */



void dcsrestore(char * dcsb)
{
 int  Pr;
 int  Pc;
 int  Pp;
 int  Srend;
 int  Satt;
 int  Sflag;
 int  Pgl;
 int  Pgr;
 int  Scss;
 char Sdesig[96];
 char * p;
 int  cs;
 int  i;
 int  n;

 if(!strcmp(dcsb,"2$t"))  /* tabs */
 {
  clearalltabs();
  dcsb+=3;

  i=0;
  while(*dcsb)
  {
   if(isdigit(*dcsb)) i=i*10+(*dcsb)-'0';
   else
   {
    if(i>=1 && i<=width) tabs[i]=1;
    i=0;
   }
   dcsb++;
  }
 }
 else
 if(!strcmp(dcsb,"1$t"))  /* other stuff */
 {
  dcsb+=3;

  if(strlen(dcsb)<96)
  {
   n=sscanf(dcsb,"%d;%d;%d;%c;%c;%c;%d;%d;%c;%s",
              &Pr,&Pc,&Pp,&Srend,&Satt,&Sflag,&Pgl,&Pgr,&Scss,&Sdesig);

   if(n==10)
   {
    vtgl=Pgl;
    vtgr=Pgr;

    Pc--;
    Pr--;
    if((Pc>=0 && Pc<width) && (Pr>=0 && Pr<24)) cursorxy(Pc,Pr);

    if(Srend>=0x40 && Srend<0x80)
    {
     rendition=0;
     if(Srend & 0x8) rendition|=64;
     if(Srend & 0x4) rendition|=16;
     if(Srend & 0x2) rendition|=8;
     if(Srend & 0x1) rendition|=1;

     if(autoprint) gorendition(rendition);
    }

    if(Satt>=0x40 && Satt<0x42) selerase=Satt & 0x1;

    if(Sflag>=0x40 && Sflag<0x80)
    {
     if(Srend & 0x8) pend=1;
     if(Srend & 0x4) vtssg3=1;
     if(Srend & 0x2) vtssg2=1;
     if(Srend & 0x1) originmode=1;
    }

    i=0;
    p=Sdesig;
    while(1)
    {
     cs=vtfindident(p);
     if(cs<0) break;
     vtgn[i++]=cs;
     p+=strlen(vtcsetmap[cs].ident);
     if(i>3) break;
    }
   }
  }
 }
}






/* report control function */

/*
   
 DCS $ q  string ST    report control function setting

          $}           set active status display
          "q           set character attribute erasable
          "p           set conformace level
          $~           set status line type
          r            set top and bottom margins
          m            set graphic rendition

 Response DCS Ps $ r string ST

          Ps==0 for valid 1 for invalid 

 */

void dcsreport(char * dcsb)
{
 int   good=1;
 char  string[64];
 char  sstring[32];
 int   sslen;
 int   i;

 if(*dcsb=='$' && *(dcsb+1)=='q')
 {
  dcsb+=2;

  if(*(dcsb+1)==0)
  {
   if(*dcsb=='r')
   {
    sprintf(string,"|[P0$r%d;%dr|[\\",scltop+1,sclbot+1);
   }
   else
   if(*dcsb=='m')
   {
    sslen=0;
    for(i=0;i<8;i++)
     if(rendition & (1<<i))
     {
      if(sslen) sstring[sslen++]=';';
      sstring[sslen++]=i+'0';
     }
    sprintf(string,"|[P0$r%smr|[\\",sstring);
   }
   else
    good=0;
  }
  else
  if(*dcsb=='"')
  {
   if(*(dcsb+1)=='q')
   {
    sprintf(string,"|[P0$r%d\"q|[\\",selerase);
   }
   else
   if(*(dcsb+1)=='p')
   {
    sprintf(string,"|[P0$r%d;%d\"p|[\\",vt220?63:61,c1codes?0:1);
   }
   else
    good=0;
  }
  else
  if(*dcsb=='$')
  {
   if(*(dcsb+1)=='}')
   {
    sprintf(string,"|[P0$r%d${|[\\",ttyy==24);
   }
   else
   if(*(dcsb+1)=='~')
   {
    sprintf(string,"|[P0$r%d$~|[\\",vtstatus);
   }
   else
    good=0;
  }
 }
 else
    good=0;

 if(!good) sprintf(string,"|[P1$r|[\\");

/* now send the report */

 vtconvertstringline(string);
}







/* assign upss */
/*
   DCS Ps !u string ST   assign upss

                       Ps=0 94 chars
                       Ps=1 96
                       string ident
 */


void dcsassign(char * dcsb)
{
 int n;
 int size;
 int cs;

 n=sscanf(dcsb,"%d",&size);

 if(n==1)
 {
  while(*dcsb)
  {
   if(*dcsb++=='u') break;
  }

  if(*dcsb)
  {
   cs=vtfindident(dcsb);
   if(cs>=0) vtupss=cs;
  }
 }
}







#define DCSCHUNK 128

void dcsst(int byte)
{
 static char * dcsp;
 static int    dcsb;
 static int    dcsk; 
 static int    dcsx;
 static int    dcst;
 static int    seendollar;
 static int    seenpling;


 int npar;
 int val1;
 int val2;

 int code;


 if(byte<0)      /* one of starting states */
 {
  if(byte==DCSST)
  {
   /* we've accumulated a string */

   switch(dcst)
   {
    case DCSDEFCHAR:               /* define a char */
                    dcsdefinechar(dcsp);
                    break;

     case DCSRESTPS:               /* restore presenation state */
                    dcsrestore(dcsp);
                    break;

      case DCSREPCF:               /* report control function */
                    dcsreport(dcsp);
                    break;

      case DCSAUPSS:               /* assign upss */
                    dcsassign(dcsp);
                    break;
   }
  }

  dcst=byte;
  dcsb=0;

  if(dcsp) flex_chunk((flex_ptr)&dcsp,dcsb,DCSCHUNK);
  else     flex_alloc((flex_ptr)&dcsp,DCSCHUNK);

  seendollar=seenpling=0;

  if(dcst==DCSST) dcs=0;
  else            dcs=1;
 }
 else
 if(dcst==DCSPM || dcst==DCSOSC || dcst==DCSAPC)
 {
  /* ignore */


 }
 else
 {
  dcsp[dcsb]=byte;
  dcsp[dcsb+1]=0;

  if(flex_chunk((flex_ptr)&dcsp,dcsb,DCSCHUNK)) dcsb++;

  if(dcst==DCSDCS)
  {
   if(byte=='$' && !seendollar) seendollar=1;
   else
   if(byte=='!' && !seenpling)  seenpling=1;
   else
   if(byte=='|')      /* we're going to define keys */
   {
    npar=sscanf(dcsp,"%d;%d",&val1,&val2);
    if(npar==1 && !val1) setvt220k();
    if(npar==2) flock=!val2;
    dcst=DCSDCS1;
    dcsk=-1;
    dcsb=0;
   }
   else
   if(byte=='{')     /* we're going to define a char */
   {
    dcst=DCSDEFCHAR;
   }
   else
   if(byte=='p' && seendollar)   /* download state info */
   {
    dcst=DCSDLDSI;
   }
   else
   if(byte=='t' && seendollar)  /* restore presenation state */
   {
    dcst=DCSRESTPS;
   }
   else
   if(byte=='q' && seendollar)  /* report control function */
   {
    dcst=DCSREPCF;
   }
   else
   if(byte=='u' && seenpling)   /* assign upss */
   {
    dcst=DCSAUPSS;
   }
   else
   if(!isdigit(byte) && byte!=';') dcst=DCSIGNORE;
  }
  else 
  if(byte=='/' && dcst==DCSDCS1)
  {                             /* there should be a key no in the buffer */
   if(sscanf(dcsp,"%d/",&dcsk))
   {
    dcsx=0;
    dcst=DCSDCS2;      /* dcsk is DEC key number! */

    if(dcsk>30) dcsk-=14;
    else
    if(dcsk>27) dcsk-=13;
    else
    if(dcsk>22) dcsk=-12;
    else        dcsk-=11;

    if(dcsk<6 || dcsk>20) dcsk=-1;
    else                  vt220writekey(dcsk-6,0,0);
   }
   dcsb=0;
  }
  else
  if(byte==';' && dcst==DCSDCS2)      /* finished defining key */
  {
   dcst=1;
   dcsk=-1;
   dcsb=0;
  }
  else
  if(dcsb==2 && dcst==DCSDCS2)
  {                                  /* transfer hex byte to key */
                                     /* remembering to put a zero on the end */
   if(dcsb==2 && dcsk>=5 && dcsk<=20)
   if(sscanf(dcsp,"%x",&code))
   if(dcsx<512)
   {
    vt220writekey(dcsk-6,dcsx,code);
    dcsx++;
   }
   dcsb=0;
  }
 }
}



/*****************************************************************************/



void vtkeycodeslo(int key)
{
 if(keylockmode && !ansisys) beep();
 else                        vtkeyline(key);
}



void vtkeycodeslostring(char * string)
{
 int len=strlen(string);
 int i;
 for(i=0;i<len;i++) vtkeycodeslo(string[i]);
}



/* keyboard out for TTY */

void ttykey(int * key)
{
 int subk;
 int c=*key;

 if(c==CR && txcrlnf)
 {
  vtkeycodeslo(CR);
  vtkeycodeslo(LF);
 }
 else
 {
  subk=c & 0xFCF;
  if(subk>=CLEFT & subk<=CUP) vtkeycodeslo(subk-CLEFT+8);
  else 
  if(c==TAB)                  vtkeycodeslo(HT);
  else                         
  if(c==BACKSPACE)            vtkeycodeslo(BS);
  else 
  if(c<0x100)                 vtkeycodeslo(c);
  else                        
                              return;
 }

 *key=-1;
}






int vt100m[18]=
{
 K0,
 K1,
 K2,
 K3,
 K4,
 K5,
 K6,
 K7,
 K8,
 K9,
 NUMLOCK,     /* 10 */
 KSLASH,      /* 11 */
 KASTERIX,    /* 12 */
 KHASH,       /* 13 */
 KPLUS,       /* 14 */
 KMINUS,      /* 15 */
 KPOINT,      /* 16 */
 ENTER        /* 17 */
};




/* setvtkeymap(int vtkey,string & acornkey); */
/* 0<=vtkey<=17                              */
/* 

 K0,
 K1,
 K2,
 K3,
 K4,
 K5,
 K6,
 K7,
 K8,
 K9,
 NUMLOCK,
 KSLASH, 
 KASTERIX,
 KHASH,   
 KPLUS,   
 KMINUS,
 KPOINT,
 ENTER

*/



void setvtkeymap(int fp)
{
 int    vtindex;
 char * p;
 int    acode;

 vtindex=stack[fp];
 if(vtindex>=0 && vtindex<18)
 {
  p=stringptr(stack[fp+1]);
  acode=keytype(p);
  if(acode>=0) vt100m[vtindex]=acode;
 }
}



int vtinset(int table[],int size,int code)
{
 int i;

 for(i=0;i<size;i++)
  if(table[i]==code) return(i);
 
 return(-1);
}



/* keyboard output for VT terminals */

void vt100key(int * key)
{
 int c;
 int d;

 c=*key;

 if(c==163 && ansisys)  c=156;
 else
 if(c==163 && !ansisys) c=35;


 if(c==BACKSPACE)
 {
  if(vtswopbs) c=DEL;
  else         c=BS;
 }
 else
 if(c==DEL && vtswopbs) c=BS;


 if(c==CR && (newlinemode || txcrlnf))
 {
  vtkeycodeslo(CR);
  vtkeycodeslo(LF);
 }
 else
 if(c==TAB)      vtkeycodeslo(HT);
 else
 if(c<0x100)     vtkeycodeslo(c);
 else
 if(c==SHFT_TAB) vtkeycodeslo(BS);
 else
 if(c>=CLEFT && c<=CUP)
 {
  vtkeycodeslo(ESC);
  if(ansimode)
  {
   if(cursorkeymode) vtkeycodeslo('[');
   else              vtkeycodeslo('O');
  }
  vtkeycodeslo('D'-(c-CLEFT));
 }
 else
 if((d=vtinset(vt100m,sizeof(vt100m)/sizeof(int),c))>=0)
 { 
  if(d>=10 && d<=13)
  {
   vtkeycodeslo(ESC);
   if(ansimode) vtkeycodeslo('O');
   else 
   if(altkey)   vtkeycodeslo('?');
   vtkeycodeslo('P'+d-10);
  }
  else
  if(altkey || keypadmode)
  {
   vtkeycodeslo(ESC);
   if(ansimode) vtkeycodeslo('O'); 
   else         vtkeycodeslo('?');
   if(d<10)     vtkeycodeslo('p'+d);
   else
   if(d<17)     vtkeycodeslo('l'+d-14);
   else         vtkeycodeslo('M');
  }
  else
  {
   if(d<10)     vtkeycodeslo('0'+d);
   else 
   if(d==14)    vtkeycodeslo('+');
   else 
   if(d==15)    vtkeycodeslo('-');
   else
   if(d==16)    vtkeycodeslo('.');
   else
   if(d==17)    vtkeycodeslo(CR);
  }
 }
 else
                return;
 *key=-1;
}




int vt220m[21]=
{
  ACT_HOME,
  ACT_INSERT,
  ACT_DEL,
  ACT_COPY,
  ACT_PAGEUP,
  ACT_PAGEDOWN,

  ACT_F1,
  ACT_F2,
  ACT_F3,
  ACT_F4,
  ACT_F5,
  ACT_F6,
  ACT_F7,
  ACT_F8,
  ACT_F9,
  ACT_F10,
  ACT_F11,
  ACT_F12,
  ACT_PRINTK,
  ACT_SL,
  ACT_BREAK
};



void vt220key(int * key)
{
 int i;
 int c;
 char string[32];

 c=*key;

 for(i=0;i<21;i++) if(vt220m[i]==c) break;

 if(i==21) vt100key(key);
 else
 {
  if(i<6)
  {
   sprintf(string,"\33[%d~",i+1);
   vtkeycodeslostring(string);
  }
  else
  {
   if(flock) beep();
   else      vtkeycodeslostring(vt220fnkeys[i-6]);
  }
  *key=-1;
 }
}




/* called direct from wimps */

void vtkey(int * key)
{
 int ch=*key;



 switch(ch)
 {
     case F1:                        /* show quick set up */
             popquicksetup();
             break;

     case F2:                        /* show directory */
             dirshow();
             break;

     case F3:
             if(vtselect) opensave(SAVEVTSELECT);
             else         opensave(SAVEVTBUFF);
             break;

     case F4:
             connect();
             break;

     case F5:
             ftpreceive();
             break;

     case F6:
             openrxbatch();
             break;

     case F7:
             macrosshow();
             break;

     case F8:
             longbreak();
             break;

     case F9:
             spoolon();
             break;

    case F10:
             vthold();
             break;

    case F11:
             vtautoprinton();
             break;

 case PRINTK:
             if(tekopen) poptekprint();
             else        printscreen();
             break;

case SHFT_F1:
             answerback();
             break;

case SHFT_F2:
             diallast();
             break;

case SHFT_F3:
             opensave(SAVEVTSCREEN);
             break;

case SHFT_F4:
             disconnect();
             break;

case SHFT_F5:
             ftpsend();
             break;

case SHFT_F6:
             opentxbatch();
             break;

case SHFT_F7:
             vttogglestatus();
             break;

case SHFT_F8:
             shortbreak();
             break;

case SHFT_F9:
             spooloff();
             break;

case SHFT_F10:
              vtrelease();
              break;

case SHFT_F11:
              vtautoprintoff();
              break;

/* case SHFT_F12:
              toggleced();
              break;      */


           case COPY:
                     vthomescreen();
                     break;

         case PAGEUP:
                     vtlineup();
                     break;

       case PAGEDOWN:
                     vtlinedown();
                     break;

    case SHFT_PAGEUP:
                     vtpageup();
                     break;

 
  case SHFT_PAGEDOWN:
                     vtpagedown();
                     break;

    case CTRL_PAGEUP:
                     vtgostart();
                     break;

  case CTRL_PAGEDOWN:
                     vtgoend();
                     break;

             default:
                     vtremzone();

                     if((tekexists && !tektextplane) || ttymode) ttykey(key);
                     else
                     if(vt220)      vt220key(key);
                     else
                                    vt100key(key);
                     return;
 }

 *key=-1;
}


/* used to send key codes from inside terminal */
/* e.g. from mouse clicks                      */

void vtintkey(int key)
{
 vtkey(&key);
}


/*****************************************************************************/
                                 /* CED */


#define CEDLINELEN 82
#define CEDLINES   32


int    cedup;   /* =1 means CED active */
int    cedpoi;  /* current line */
char * cedbuff;


void cedgetline(void)
{
 writeicon(whandle[CED],0,cedbuff+CEDLINELEN*cedpoi);
 iecarrot(whandle[CED],0);
}


void cedputline(void)
{
 char * buff;
 char * line;

 buff=cedbuff+CEDLINELEN*cedpoi;
 line=iconaddr(whandle[CED],0);

 memcpy(buff,line,CEDLINELEN);
}


/* where do we send bytes to ? maybe use termmode to work it out */

void cedtermkey(int * key)
{
 if(terminalmode==TMODEVX) viewkey(key);
 else
 if(terminalmode==TMODEVT) vtkey(key);
}



int cedsendkey(int key)
{
 cedtermkey(&key);
 return(0);
}


void kprints(int fp)
{
 char string[256];
 strcpy(string,stringptr(stack[fp]));
 expandmacro(cedsendkey,string);
}



void cedkey(int * key)
{
 int c=*key;

 switch(c)
 {
    case  CR:                 /* send line */
             expandmacro(cedsendkey,iconaddr(whandle[CED],0));
             cedsendkey(CR);
             /* drop      */

  case 0x18E:  /* next line */
             cedputline();
             if(++cedpoi==CEDLINES) cedpoi=0;
             cedgetline();
             break;

  case 0x18F:  /* previous line */
             cedputline();
             if(cedpoi--==0) cedpoi=CEDLINES-1;
             cedgetline();
             break;

     default:
             if(c>=0x100) cedtermkey(key);
             return;
             break;
             
 }

 *key=-1;
}


void openced(void)
{
 int handle;

 if(!cedup)
 {
  if(flex_alloce((flex_ptr)&cedbuff,CEDLINES*CEDLINELEN))
  {
   memset(cedbuff,0,CEDLINES*CEDLINELEN);

   cedpoi=0;
   handle=createwindow(CED);
   open(handle,0,112,1280,112+36,0,0,-1);   /* min 104 + 36 */
   cedgetline();
   cedup=1;
  }
 }
}


void closeced(void)
{
 if(cedup)
 {
  flex_free((flex_ptr)&cedbuff);
  cedup=0;
  closedownt(CED);
 }
}




void toggleced(void)
{
 if(cedup) closeced();
 else      openced();
}




